package com.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.entity.ServerInfo;
import com.example.entity.ServerMonitorData;
import com.example.entity.ServerDailyStats;
import com.example.mapper.ServerInfoMapper;
import com.example.mapper.ServerMonitorDataMapper;
import com.example.mapper.ServerDailyStatsMapper;
import com.example.service.ServerMonitorService;
import com.example.util.SystemMonitorUtil;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;

/*import javax.annotation.PostConstruct;*/

/**
 * 服务器监控Service实现类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class ServerMonitorServiceImpl implements ServerMonitorService {
    
    private final ServerInfoMapper serverInfoMapper;
    private final ServerMonitorDataMapper monitorDataMapper;
    private final ServerDailyStatsMapper dailyStatsMapper;
    private final JavaMailSender mailSender;
    
    // 本机服务器信息
    private ServerInfo localServerInfo;
    
    /**
     * 系统启动时初始化本机服务器信息
     */
    @PostConstruct
    public void initLocalServerInfo() {
        try {
            // 获取本机主机名和IP地址
            InetAddress localHost = InetAddress.getLocalHost();
            String hostName = localHost.getHostName();
            String ipAddress = localHost.getHostAddress();
            
            // 查询数据库中是否有该IP地址的服务器记录
            LambdaQueryWrapper<ServerInfo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ServerInfo::getIpAddress, ipAddress);
            ServerInfo existingServer = serverInfoMapper.selectOne(queryWrapper);
            
            if (existingServer != null) {
                // 如果已存在记录，则使用该记录
                localServerInfo = existingServer;
                log.info("找到本机服务器记录: ID={}, 名称={}, IP={}", 
                         localServerInfo.getId(), localServerInfo.getServerName(), localServerInfo.getIpAddress());
            } else {
                // 如果不存在，则创建新记录
                ServerInfo newServer = new ServerInfo();
                newServer.setServerName(hostName);
                newServer.setIpAddress(ipAddress);
                // 设置默认阈值
                newServer.setCpuThreshold(80.0);
                newServer.setMemoryThreshold(80.0);
                newServer.setDiskThreshold(80.0);
                newServer.setAlertEmail("swords@88.com");
                newServer.setAlertInterval(30);
                
                // 保存到数据库
                serverInfoMapper.insert(newServer);
                localServerInfo = newServer;
                log.info("创建新的本机服务器记录: ID={}, 名称={}, IP={}", 
                         localServerInfo.getId(), localServerInfo.getServerName(), localServerInfo.getIpAddress());
            }
        } catch (UnknownHostException e) {
            log.error("获取本机信息失败: {}", e.getMessage(), e);
            // 创建一个默认的本机记录
            createDefaultLocalServerInfo();
        } catch (Exception e) {
            log.error("初始化本机服务器信息失败: {}", e.getMessage(), e);
            createDefaultLocalServerInfo();
        }
    }
    
    /**
     * 创建默认的本机服务器记录
     */
    private void createDefaultLocalServerInfo() {
        try {
            // 查询数据库中是否有记录
            List<ServerInfo> servers = serverInfoMapper.selectList(null);
            if (!CollectionUtils.isEmpty(servers)) {
                // 如果有记录，使用第一条
                localServerInfo = servers.get(0);
                log.info("使用默认服务器记录: ID={}, 名称={}", localServerInfo.getId(), localServerInfo.getServerName());
                return;
            }
            
            // 如果没有任何记录，创建一个默认记录
            ServerInfo defaultServer = new ServerInfo();
            defaultServer.setServerName("本地服务器");
            defaultServer.setIpAddress("127.0.0.1");
            defaultServer.setCpuThreshold(80.0);
            defaultServer.setMemoryThreshold(80.0);
            defaultServer.setDiskThreshold(80.0);
            defaultServer.setAlertEmail("admin@example.com");
            defaultServer.setAlertInterval(30);
            
            serverInfoMapper.insert(defaultServer);
            localServerInfo = defaultServer;
            log.info("创建默认服务器记录: ID={}", localServerInfo.getId());
        } catch (Exception e) {
            log.error("创建默认服务器记录失败: {}", e.getMessage(), e);
            throw new RuntimeException("无法创建服务器记录，系统无法正常运行");
        }
    }
    
    @Override
    public ServerInfo getServerInfo(Long serverId) {
        return serverInfoMapper.selectById(serverId);
    }
    
    @Override
    public void saveServerInfo(ServerInfo serverInfo) {
        if (serverInfo.getId() == null) {
            serverInfoMapper.insert(serverInfo);
        } else {
            serverInfoMapper.updateById(serverInfo);
            
            // 如果更新的是本机服务器信息，同步更新内存中的记录
            if (localServerInfo != null && localServerInfo.getId().equals(serverInfo.getId())) {
                localServerInfo = serverInfo;
            }
        }
    }
    
    @Override
    public List<ServerMonitorData> getMonitorData(Long serverId, LocalDateTime startTime, LocalDateTime endTime) {
        return monitorDataMapper.getMonitorDataByTimeRange(serverId, startTime, endTime);
    }
    
    @Override
    public void saveMonitorData(ServerMonitorData monitorData) {
        monitorDataMapper.insert(monitorData);
    }
    
    @Override
    public void saveDailyStats(ServerDailyStats dailyStats) {
        dailyStatsMapper.insert(dailyStats);
    }
    
    /**
     * 获取指定服务器在特定时间范围内的每日统计信息。
     */
    @Override
    public List<ServerDailyStats> getDailyStats(Long serverId, LocalDateTime startTime, LocalDateTime endTime) {
        return dailyStatsMapper.getStatsByTimeRange(serverId, startTime, endTime);
    }
    
    /**
     * 获取本机服务器ID
     */
    @Override
    public Long getLocalServerId() {
        // 确保本机服务器信息已初始化
        if (localServerInfo == null) {
            initLocalServerInfo();
        }
        return localServerInfo.getId();
    }
    
    /**
     * 检查服务器状态并发送警报
     */
    @Override
    public void checkAndSendAlert(Long serverId) {
        // 获取服务器信息
        ServerInfo serverInfo = getServerInfo(serverId);
        if (serverInfo == null) {
            return;
        }

        // 获取最新的监控数据
        LambdaQueryWrapper<ServerMonitorData> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ServerMonitorData::getServerId, serverId)
                .orderByDesc(ServerMonitorData::getCollectTime)
                .last("LIMIT 1");
        ServerMonitorData latestData = monitorDataMapper.selectOne(wrapper);

        if (latestData == null) {
            return;
        }

        // 检查是否超过阈值
        boolean needAlert = false;
        StringBuilder alertMessage = new StringBuilder();

        // 检查CPU使用率是否超过阈值
        if (latestData.getCpuUsage() > serverInfo.getCpuThreshold()) {
            needAlert = true;
            alertMessage.append("CPU使用率: ").append(latestData.getCpuUsage()).append("%\n");
        }
        // 检查内存使用率是否超过阈值
        if (latestData.getMemoryUsage() > serverInfo.getMemoryThreshold()) {
            needAlert = true;
            alertMessage.append("内存使用率: ").append(latestData.getMemoryUsage()).append("%\n");
        }
        // 检查磁盘使用率是否超过阈值
        if (latestData.getDiskUsage() > serverInfo.getDiskThreshold()) {
            needAlert = true;
            alertMessage.append("磁盘使用率: ").append(latestData.getDiskUsage()).append("%\n");
        }
        
        // 发送报警邮件
        if (needAlert) {
            SimpleMailMessage message = new SimpleMailMessage();
            message.setTo(serverInfo.getAlertEmail());
            message.setSubject("服务器资源使用率报警");
            message.setText("服务器: " + serverInfo.getServerName() + "\n" +
                    "IP地址: " + serverInfo.getIpAddress() + "\n" +
                    "报警时间: " + LocalDateTime.now() + "\n" +
                    "报警内容:\n" + alertMessage);
            mailSender.send(message);
        }
    }
    
    /**
     * 每分钟采集一次监控数据
     */
    @Scheduled(cron = "0 * * * * ?")
    public void collectMonitorData() {
        try {
            // 确保本机服务器信息已初始化
            if (localServerInfo == null) {
                initLocalServerInfo();
            }
            
            ServerMonitorData monitorData = new ServerMonitorData();
            monitorData.setServerId(localServerInfo.getId());
            
            // 使用工具类获取系统资源使用情况
            try {
                String diskPath = System.getProperty("os.name").toLowerCase().contains("windows") ? "C:" : "/";
                monitorData.setCpuUsage(SystemMonitorUtil.getCpuUsage());
                monitorData.setMemoryUsage(SystemMonitorUtil.getMemoryUsage());
                monitorData.setDiskUsage(SystemMonitorUtil.getDiskUsage(diskPath));
            } catch (Exception e) {
                // 发生异常时记录日志并设置默认值
                log.error("获取系统资源使用率出错: {}", e.getMessage(), e);
                monitorData.setCpuUsage(0.0);
                monitorData.setMemoryUsage(0.0);
                monitorData.setDiskUsage(0.0);
            }
            
            monitorData.setCollectTime(LocalDateTime.now());
            saveMonitorData(monitorData);
            
            // 检查是否需要发送报警
            checkAndSendAlert(monitorData.getServerId());
        } catch (Exception e) {
            log.error("采集监控数据出错: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 每天凌晨统计前一天的数据
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void calculateDailyStats() {
        try {
            // 确保本机服务器信息已初始化
            if (localServerInfo == null) {
                initLocalServerInfo();
            }
            
            LocalDate yesterday = LocalDate.now().minusDays(1);
            LocalDateTime startTime = yesterday.atStartOfDay();
            LocalDateTime endTime = yesterday.atTime(23, 59, 59);
            
            List<ServerMonitorData> dailyData = getMonitorData(localServerInfo.getId(), startTime, endTime);
            
            if (!dailyData.isEmpty()) {
                ServerDailyStats stats = new ServerDailyStats();
                stats.setServerId(localServerInfo.getId());
                stats.setStatsDate(yesterday);
                
                // 计算统计数据
                stats.setCpuMax(dailyData.stream().mapToDouble(ServerMonitorData::getCpuUsage).max().orElse(0));
                stats.setCpuMin(dailyData.stream().mapToDouble(ServerMonitorData::getCpuUsage).min().orElse(0));
                stats.setCpuAvg(dailyData.stream().mapToDouble(ServerMonitorData::getCpuUsage).average().orElse(0));
                
                stats.setMemoryMax(dailyData.stream().mapToDouble(ServerMonitorData::getMemoryUsage).max().orElse(0));
                stats.setMemoryMin(dailyData.stream().mapToDouble(ServerMonitorData::getMemoryUsage).min().orElse(0));
                stats.setMemoryAvg(dailyData.stream().mapToDouble(ServerMonitorData::getMemoryUsage).average().orElse(0));
                
                stats.setDiskMax(dailyData.stream().mapToDouble(ServerMonitorData::getDiskUsage).max().orElse(0));
                stats.setDiskMin(dailyData.stream().mapToDouble(ServerMonitorData::getDiskUsage).min().orElse(0));
                stats.setDiskAvg(dailyData.stream().mapToDouble(ServerMonitorData::getDiskUsage).average().orElse(0));
                
                saveDailyStats(stats);
            }
        } catch (Exception e) {
            log.error("计算每日统计数据出错: {}", e.getMessage(), e);
        }
    }
} 